package di.aop;

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

/**
 * @Description: TODO
 * @Author: chris_cai@enable-ets.com
 * @Since: 2018年09月26日
 */
@Aspect
@Component
public class LogAspect {
    /**
     * @Aspect 声明该类是一个切面
     * @Pointcut 声明切点,即要拦截的方法,后面可写注解,也可以写切点表达式
     */

    @Pointcut("@annotation(di.aop.Action)")
    public void pointcut() {}

    @After("pointcut()")
    public void after(JoinPoint joinPoint) {
        System.out.println("后置通知");
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Action annotation = method.getAnnotation(Action.class);
        System.out.println("注解拦截: " + annotation.name());
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("环绕通知前");

        //这步,是执行我们目标对象的行为(目标对象自己的方法)
        Object value = pjp.proceed();

        System.out.println("环绕通知后");

        return value;
    }

    @Before(" execution(* di.service.DemoMethodService.*(..))")
    public void before(JoinPoint joinPoint) {
        System.out.println("前置通知");
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        System.out.println("切点表达式拦截: " + method.getName());
    }
}
